package com.parking.status.sync.netty.entity;

import com.parking.status.sync.netty.util.CrcHelper;

import java.io.*;

/**
 * Created by Administrator on 2015/9/15.
 */
public class MessageBody implements Serializable {

    private static final long   serialVersionUID    = 1L;

    private static int counter = 1;

//    //发送方地址  由厂商编码1-65535  和地址编码1-65535  组合而成
//    private int senderAddress;
    private short companyCode;
    private short addrCode;

    //接收方地址
    private int receiverAddress;

    //消息方向和类型
    private byte controlByte;
//    private int contentType;
//    //内容长度
//    private int contentLength;

    private byte[] content;

    private byte[] crc16 = new byte[2];

    private byte endian;

    public MessageBody(){}

    public MessageBody(short companyCode, short addrCode, int rev, ContentBase content) {
        this.companyCode = companyCode;
        this.addrCode = addrCode;
        this.receiverAddress = rev;
        //this.contentLength = content.getContentLength();
        this.content = content.serialize();
        this.controlByte = content.getControlByte();
        CrcHelper.get_crc16(this.content, this.content.length, this.crc16);
    }

    public synchronized int counterPlus() {
        return (counter ++) % 65535;
    }

    public String toString() {
        return "messagebody";
    }

    public int getReceiverAddress() {
        return receiverAddress;
    }

    public void setReceiverAddress(int receiverAddress) {
        this.receiverAddress = receiverAddress;
    }


    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    public byte getEndian() {
        return endian;
    }

    public void setEndian(byte endian) {
        this.endian = endian;
    }

    public short getCompanyCode() {
        return companyCode;
    }

    public void setCompanyCode(short companyCode) {
        this.companyCode = companyCode;
    }

    public short getAddrCode() {
        return addrCode;
    }

    public void setAddrCode(short addrCode) {
        this.addrCode = addrCode;
    }

    public byte getControlByte() {
        return controlByte;
    }

    public void setControlByte(byte controlByte) {
        this.controlByte = controlByte;

//        //同时设置
//        contentType = controlByte & 0x7F;
//        contentLength = MessageType.getContentLength(controlByte & 0x7F);
    }

    public int getContentLength() {
        return MessageType.getContentLength(controlByte & 0x7F);
    }

    public int getContentType() {
        return controlByte & 0x7F;
    }

    public byte[] getCrc16() {
        return crc16;
    }

    public void setCrc16(byte[] crc16) {
        this.crc16 = crc16;
    }



    public int getLength() {
        //帧序号 发送方地址  接收方地址 控制字数据  内容 校验字 帧尾
        //2      4          4           1       可变   2     1
        return 4 + 4 + 1 + getContentLength() + 2 + 1;
    }

    public byte[] toBytes() {
        byte[] bytes = null;
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = null;
        InputStream bis = null;
        ObjectInputStream ois = null;
        int contentlength = 0;
        try {
            oo = new ObjectOutputStream(bo);
            oo.writeShort(counterPlus()); //序号 自增
            contentlength += 2;
            oo.writeShort(companyCode);
            contentlength += 2;
            oo.writeShort(addrCode);
            contentlength += 2;
            oo.writeInt(receiverAddress);
            contentlength += 4;
            oo.writeByte(controlByte);
            contentlength += 1;
            oo.write(content);
            contentlength += content.length;
            oo.write(crc16);
            contentlength += 2;
            oo.writeByte(0xcd);
            contentlength += 1;
            oo.flush();
            bytes = bo.toByteArray();
            //再读一下去掉了头信息
            bis = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bis);
            bytes = new byte[contentlength];
            ois.readFully(bytes);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                oo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return (bytes);
    }

}
